package socket;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Server {
    private ServerSocket server;
    private ExecutorService threadPool = Executors.newFixedThreadPool(30);
    //private List<PrintWriter> allOut = Collections.synchronizedList(new ArrayList<>());
    private Map<String,PrintWriter> allOut = new ConcurrentHashMap<>();
    public Server(){
        try {
                System.out.println("正在启动服务端");
                server = new ServerSocket(9090);
                System.out.println("服务端启动成功");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public void start(){
        try {
            while (true) {
                System.out.println("等待客户端连接");
                Socket socket = server.accept();
                System.out.println("客户端已连接");
                ClientHandler handler = new ClientHandler(socket);
                threadPool.execute(handler);

            }
            } catch(IOException e){
                e.printStackTrace();
            }

    }
    public static void main(String[] args) {
        Server server = new Server();
        server.start();
    }
    private class ClientHandler implements Runnable {
        private Socket socket;
        private String host;
        private String nickname;

        public ClientHandler(Socket socket) {
            this.socket = socket;
            host = socket.getInetAddress().getHostAddress();
        }
        @Override
        public void run() {
            PrintWriter pw = null;
            try {
                InputStream in = socket.getInputStream();
                InputStreamReader isr = new InputStreamReader(in, StandardCharsets.UTF_8);
                BufferedReader br = new BufferedReader(isr);
                OutputStream ops = socket.getOutputStream();
                OutputStreamWriter osw = new OutputStreamWriter(ops, StandardCharsets.UTF_8);
                BufferedWriter bfw = new BufferedWriter(osw);
                pw = new PrintWriter(bfw, true);
                nickname = br.readLine();
                allOut.put(nickname,pw);
                sendMessage(nickname + "上线了，当前在线人数" + allOut.size());
                String line;
                while ((line = br.readLine()) != null) {
                    if (line.startsWith("@")) {
                        sendMessageToSomeone(line);
                    }else {
                        sendMessage(nickname + "(" + host + ")" + "说：" + line);
                        saveMessage(nickname,null,line);
                    }
                }
            } catch (IOException e) {
            } finally {
                allOut.remove(nickname);
                sendMessage(nickname + "下线了，当前在线人数" + allOut.size());
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        private void sendMessage(String line) {
            System.out.println(line);
            //allOut.forEach(e -> e.println(line));
            allOut.values().forEach(e->e.println(line));
    }
    private void sendMessageToSomeone(String message){
        if (message.matches("@.+:.+")){
            String toNickname = message.substring(1,message.indexOf(":"));
            if (allOut.containsKey(toNickname)){
                String toMessage = message.substring(message.indexOf(":")+1);
                toMessage = nickname + "悄悄对你说" + toMessage;
                allOut.get(toNickname).println(toMessage);
                allOut.get(nickname).println("消息已发送给"+ toNickname);
                saveMessage(nickname,toNickname,toMessage);
            }else {
                allOut.get(nickname).println("用户["+ nickname + "]不存在");
            }
        }else {
            allOut.get(nickname).println("私聊格式错误，正确格式[@昵称：聊天信息]");
        }
    }

        private void saveMessage(String fromUser,String toUser,String message){
            try(Connection connection = DBUtil.getConnection()) {
                String sql = "INSERT INTO chatinfo(from_user,to_user,content)" +
                        "VALUES(?,?,?)";
                PreparedStatement ps = connection.prepareStatement(sql);
                ps.setString(1,fromUser);
                ps.setString(2,toUser);
                ps.setString(3,message);
                ps.executeUpdate();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

